import remixlab.malla.*;

Malla malla;
int px0, px1, py0, py1;
int mx0, mx1, my0, my1;
int r, x, y;
int x0, y0;

void setup() {
  size(640, 640, P2D);
  frameRate(15);
  smooth();
  malla = new Malla(this);
  malla.setNumOfColumn(40);
  malla.initialize();
  background(255);
  noFill();
}


void draw() {
  noFill();
  malla.drawMalla();
  if(mousePressed){
    line(x0, y0, mouseX, mouseY);
  }
  stroke(206);
}

void mousePressed(){
  malla.cleanMalla();
  // in this case the position of the mouse is (0,0)
  x0 = mouseX;
  y0 = mouseY;
  mx0 = malla.whereIsX(mouseX);
  my0 = malla.whereIsY(mouseY);
}

void mouseDragged(){
  stroke(0);
  // debe existir una forma de blockear el arrastre de una linea a una determinada distancia
  // el radio puede ser mas grande que el tamanio de la malla y aparecer un error de ArrayIndexOutOfBoundsException
  line(x0, y0, mouseX, mouseY);
  stroke(206);
}

void mouseReleased(){
  mx1 = malla.whereIsX(mouseX);
  my1 = malla.whereIsY(mouseY);
  stroke(206);
  x = (int)sq(mx1-mx0);
  y = (int)sq(my1-my0);
  r = (int)sqrt(x + y);
  //println("El radio es: "+ r);
  // but when we want to draw a circle we need pass the center in this case px0 and py0 and
  // the radio, we dont have the radio but is ease to calculate, we must calculate it with the points px0,px1,py0,py1
  plotCircle(mx0, my0, r);
}

void plotCircle(int cx, int cy, int r){
  int x, y;
  int deltaX, deltaY, radiusError;
  
  x = r;
  y = 0;
  // deltaX = (1 - 2x)
  deltaX = 1 - 2*r;
  // deltaY = (2y + 1)
  deltaY = (2*y + 1);
  // radiusError = x*x + y*y -r*r
  radiusError = (int)(sq(x) + sq(y) - sq(r));
  while( x >= y ){
    plot8CirclePoints(x, y);
    y = y + 1;
    radiusError = radiusError + deltaY;
    deltaY = deltaY + 2;
    if( (2*radiusError + deltaX) > 0){
      x = x - 1;
      radiusError = radiusError + deltaX;
      deltaX = deltaX + 2;
    }
  }
}

void plot8CirclePoints(int x, int y){
  malla.drawPoint(mx0+x,my0+y); //point in octant 1
  malla.drawPoint(mx0+y,my0+x); //point in octant 2
  malla.drawPoint(mx0-y,my0+x); //point in octant 3
  malla.drawPoint(mx0-x,my0+y); //point in octant 4
  malla.drawPoint(mx0-x,my0-y); //point in octant 5
  malla.drawPoint(mx0-y,my0-x); //point in octant 6
  malla.drawPoint(mx0+y,my0-x); //point in octant 7
  malla.drawPoint(mx0+x,my0-y); //point in octant 8
}
